//SVGTransformer.cpp
//
#include <windows.h>
#include <limits>
#include <algorithm>
#include "stdafx.h"
#define EXPORTING_DLL
#include "SVGTransformer.h"
#include "SVGDrawing.h"
using namespace std;

//aqua black	blue	fuchsia gray	green	lime	maroon navy	 olive	purple	
//red silver	teal	yellow

const int strokeColorCount = 24;
const double factor =300;
_bstr_t svgcolor[strokeColorCount] = {_T("yellow"), _T("blue"), _T("green"), _T("red"), _T("aqua"), 
_T("fuchsia"), _T("gray"), _T("lime"), _T("maroon"), _T("navy"), _T("olive"), _T("purple"), _T("silver"),
_T("teal"), _T("brown"),_T("chocolate"), _T("blueviolet"), _T("hotpink"), _T("cadeblue"), _T("burlywood"),
_T("cornflowerblue"), _T("coral"), _T("darksalmon"), _T("black")};

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    return TRUE;
}

_bstr_t makeXPath(_bstr_t xpath1, int i, _bstr_t xpath2)
{
	if (i<0)
	{
		cerr<<"Error: "<<endl;
		exit(1);
	}
	if (i>0)
	{
		_bstr_t temp = _T("[");
		_bstr_t temp1 = (_variant_t)(int)i;
		temp+=temp1;
		temp+=_T("]");
		xpath1+=temp;
		xpath1+=xpath2;
	}
	return xpath1;
}

/*
// draw upper horizontal slash
void drawUpperSlash(SVGDrawing &Transformer, double x1, double y1, double length, unsigned int amount)
{
	double unit = length/amount;
	for (unsigned int i=0; i<amount; i++)
	{
		Transformer.createLine(x1, y1, x1+unit, y1-unit);
		x1=x1+unit;
	}
}

// draw under horizontal slash
void drawUnderSlash(SVGDrawing &Transformer, double x1, double y1, double length, unsigned int amount)
{
	double unit = length/amount;
	for (unsigned int i=0; i<amount; i++)
	{
		Transformer.createLine(x1, y1+unit, x1+unit, y1);
		x1=x1+unit;
	}
}

void drawLeftSlash(SVGDrawing &Transformer, double x1, double y1, double length, unsigned int amount)
{
	double unit = length/amount;
	for (unsigned int i=0; i<amount; i++)
	{
		//Transformer.createLine(x1, y1+unit, x1, y1);
		Transformer.createLine(x1-unit, y1+unit, x1, y1);
		y1=y1+unit;
	}
}
*/

void drawUpperNominalDiameter(SVGDrawing &Transformer, double x, double y, double length, double sx, double sy)
{
	int amount = length/sx;
	double dx = sx;
	double dy = sy;
	
	double startx = x+dx;

	double starty = y+dy;
	Transformer.createLine(startx, starty, startx+length, starty);
	
	for (int i=0; i<amount; i++)
	{
		Transformer.createLine(startx, starty, startx+dx, starty-dy);
		startx=startx+dx;
	}
	
	/*
	while (startx<x+length)
	{
		Transformer.createLine(startx, starty, startx+dx, starty-dy);
		startx=startx+dx;
	}
	*/
}

void drawUnderNominalDiameter(SVGDrawing &Transformer, double x, double y, double length, double sx, double sy)
{
	int amount = length/sx;
	double dx = sx;
	double dy = sy;
	
	double startx = x+dx;

	double starty = y+dy;
	Transformer.createLine(startx, starty, startx+length, starty);
	
	for (int i=0; i<amount; i++)
	{
		Transformer.createLine(startx, starty+dy, startx+dx, starty);
		startx=startx+dx;
	}

}

void drawLeftWindowHeight(SVGDrawing &Transformer, double x, double y, double length, double sx, double sy)
{
	int amount = length/sy;
	double dx = sx;
	double dy = sy;
	
	double startx = x+dx;

	double starty = y+dy;
	Transformer.createLine(startx, starty, startx, starty+length);
	
	for (int i=0; i<amount; i++)
	{
		Transformer.createLine(startx-dx, starty+dy, startx, starty);
		starty=starty+dy;
	}
}

void drawCore(LPCTSTR &fpath, SVGDrawing &Transformer, CHandler *PHandler, void * handler)
{
	//_bstr_t corepath=_T("/_TdsDesignData_/_Data_/TechData/ActivePart/Core");
	_bstr_t corepath=_T("/_TdsDesignData_/C_Data_/TechData/ActivePart/Core");
	_bstr_t nominaldiameter = corepath+_T("/NominalDiameter");
	_bstr_t windowheight = corepath+_T("/WindowHeight[1]");//makeXPath(corepath, 1, _T("/WindowHeight"));
	//double slashX = 10;
	//double slashY = 3;
	//get the value of Nominal Diameter
	double dNominalDiameter = PHandler->getValueDouble(nominaldiameter, handler)*factor;
	//get the value of WindowHeight[1] 
	double dWindowHeight = PHandler->getValueDouble(windowheight, handler)*factor;
	
	drawUpperNominalDiameter(Transformer, 0, 0, dNominalDiameter, 10, 3);
	drawUnderNominalDiameter(Transformer, 0, dWindowHeight, dNominalDiameter, 10, 3);
	drawLeftWindowHeight(Transformer, 0, 0, dWindowHeight, 10, 3);
	//Transformer.createLine(100,100,100+dNominalDiameter,100);
	//drawUpperSlash(Transformer, 100, 100, dNominalDiameter, 30);
	
	//Transformer.createLine(100,100,100,100+dWindowHeight);
	//drawUnderSlash(Transformer, 100, 100+dWindowHeight, dNominalDiameter, 30);
	
	//Transformer.createLine(100,100+dWindowHeight,100+dNominalDiameter,100+dWindowHeight);
	//drawLeftSlash(Transformer, 100, 100, dWindowHeight, 50);
	//_bstr_t te = _T("Transformer");
}


void drawWindingRect(LPCTSTR &fpath, SVGDrawing &Transformer, CHandler *PHandler, void * handler)
{
	double minrInner = 0;
	double maxzTop = 0;
	//double factor =300;
	int count=0;
	//_bstr_t windingpath=_T("/_TdsDesignData_/_Data_/TechData/ActivePart/Winding");
	_bstr_t windingpath=_T("/_TdsDesignData_/C_Data_/TechData/ActivePart/Winding");
	int windingCount = PHandler->getCount(windingpath,handler);
	for (int i=1; i<=windingCount; i++)
	{

		_bstr_t currentpath = makeXPath(windingpath, i, _T("/CurrentPath"));
		int currentpathCount = PHandler->getCount(currentpath, handler);
		
		for (int j=1; j<=currentpathCount; j++)
		{
			_bstr_t coordinatepath = makeXPath(currentpath, j, _T("/Coordinate"));
			int coordinateCount = PHandler->getCount(coordinatepath, handler);
			for (int k=1; k<=coordinateCount; k++)
			{
				_bstr_t rInner = makeXPath(coordinatepath, k, _T("/rInner"));
				_bstr_t rOuter = makeXPath(coordinatepath, k, _T("/rOuter"));
				_bstr_t zBottom = makeXPath(coordinatepath, k, _T("/zBottom"));
				_bstr_t zTop = makeXPath(coordinatepath, k, _T("/zTop"));
				
				double dInner = PHandler->getValueDouble(rInner, handler)*factor;
				double dOuter = PHandler->getValueDouble(rOuter, handler)*factor;
				double dBottom = PHandler->getValueDouble(zBottom, handler)*factor;
				double dTop = PHandler->getValueDouble(zTop, handler)*factor;
				if (i==1 && j==1 && k==1) minrInner = dInner;
				minrInner = min(minrInner, dInner);
				maxzTop = max(maxzTop, dTop);
			}
		}
	}
	int scc = 0;
	for (int i=1; i<=windingCount; i++)
	{	
		_bstr_t currentpath = makeXPath(windingpath, i, _T("/CurrentPath"));
		int currentpathCount = PHandler->getCount(currentpath, handler);
		
		for (int j=1; j<=currentpathCount; j++)
		{
			if(scc<strokeColorCount)
				scc++;
			_bstr_t coordinatepath = makeXPath(currentpath, j, _T("/Coordinate"));
			int coordinateCount = PHandler->getCount(coordinatepath, handler);
			for (int k=1; k<=coordinateCount; k++)
			{
				_bstr_t rInner = makeXPath(coordinatepath, k, _T("/rInner"));
				_bstr_t rOuter = makeXPath(coordinatepath, k, _T("/rOuter"));
				_bstr_t zBottom = makeXPath(coordinatepath, k, _T("/zBottom"));
				_bstr_t zTop = makeXPath(coordinatepath, k, _T("/zTop"));
				
				double dInner = PHandler->getValueDouble(rInner, handler)*factor;
				double dOuter = PHandler->getValueDouble(rOuter, handler)*factor;
				double dBottom = PHandler->getValueDouble(zBottom, handler)*factor;
				double dTop = PHandler->getValueDouble(zTop, handler)*factor;
				double ty = maxzTop-dTop;
				double tx = dInner-minrInner;
				
				if((windingCount*currentpathCount)<=strokeColorCount)
					Transformer.setFillColor(svgcolor[scc]);
				else
					Transformer.setFillColor(_T("black"));
					
				Transformer.createRect(tx, ty, dOuter-dInner, dTop-dBottom);

				count++;
			}
		}
	}
	cout<<count<<endl;

}
void draw(LPCTSTR fpath)
{
	SVGDrawing Transformer;
	_bstr_t path(_T(""));
	CHandler *PHandler;
	PHandler = new CHandler(path);
	
	// read data file with house information
	void * handler = PHandler->initHandlerFromFile(fpath, NULL);

	drawWindingRect(fpath, Transformer, PHandler, handler);
	drawCore(fpath, Transformer, PHandler, handler);
	delete PHandler;
	Transformer.saveToFile(".//TdsDesign.svg");
}
